package com.code.generator.cn.controller;

import com.code.generator.cn.entity.CoderField;
import com.code.generator.cn.entity.CoderTable;
import com.code.generator.cn.model.LayPageModel;
import com.code.generator.cn.service.ICoderFieldService;
import com.code.generator.cn.service.ICoderTableService;
import com.code.generator.cn.util.base.MyStringChangeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.sql.*;
import java.util.*;

import org.apache.commons.lang.StringUtils;

@Slf4j
@RestController
public class IndexController {


    DatabaseMetaData databaseMetaData = null;

    Connection conn = null;

    private String data = null;

    @Autowired
    private ICoderTableService coderTableService;

    @Autowired
    private ICoderFieldService coderFieldService;


    /**
     * 项目生成主页面
     *
     * @return
     */
    @RequestMapping("/")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView("/index");
        return mv;
    }

    /**
     * 项目生成主页面
     *
     * @return
     */
    @RequestMapping("/main")
    public ModelAndView getTables() {
        ModelAndView mv = new ModelAndView("/main/main");
        return mv;
    }


    /**
     * 获取所有的表的信息
     *
     * @return
     */
    @RequestMapping("/table")
    public Object table(HttpServletRequest request) {
        List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
        List<CoderTable> respose = null;
        try {
            DatabaseMetaData databaseMetaData = getConnection(request);
            data = conn.getCatalog();
            createTbaleByData(maps, databaseMetaData);
            respose = coderTableService.getTables(maps, data);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("数据库链接失败");
        }
        return new LayPageModel("0", 0, respose);
    }

    /**
     * 组装数据中获取的所有表名
     *
     * @param maps
     * @param databaseMetaData
     * @throws SQLException
     */
    private void createTbaleByData(List<Map<String, Object>> maps, DatabaseMetaData databaseMetaData) throws SQLException {
        ResultSet resultSet = databaseMetaData.getTables(null, "%", "%", null);
        while (resultSet.next()) {
            Map<String, Object> map = new HashMap<String, Object>();
            //获取数据库所有表名
            String tableName = resultSet.getString("TABLE_NAME");
            map.put("name", tableName);
            map.put("data", data);

            String modifyName= MyStringChangeUtil.changeField(tableName,1);
            map.put("modifyName",modifyName);
            maps.add(map);
        }
    }


    /**
     * 获取所数据库所有字段属性
     *
     * @param request
     */

    @RequestMapping("/getField")
    public Object getField(HttpServletRequest request, @RequestParam String id) {
        List<Map<String, Object>> columns = new ArrayList<Map<String, Object>>();
        List<CoderField> coderFields =new ArrayList<>();
        CoderTable coderTable = coderTableService.getById(id);
        try {
            ResultSet pk = databaseMetaData.getPrimaryKeys(null, data, coderTable.getTableName());
            //获取表主键：
            String primary = "";
            while (pk.next()) {
                primary = (String) pk.getObject(4);
            }
            ResultSet rs = databaseMetaData.getColumns(null, "%", coderTable.getTableName(), "%");
            while (rs.next()) {
                Map<String, Object> map = createMapByData(rs, primary, id);
                columns.add(map);
            }
            coderFields = coderFieldService.getAllFields(id,columns);
        } catch (SQLException e) {
            log.error("数据读写失败");
        }
        return new LayPageModel("0", coderFields.size(), coderFields);
    }


    /**
     * 获取DatabaseMetaData
     *
     * @param request
     * @return
     * @throws ClassNotFoundException
     * @throws SQLException
     */


    private DatabaseMetaData getConnection(HttpServletRequest request)
            throws ClassNotFoundException, SQLException {
        //获取url
        String url = request.getParameter("url")+"?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false";
        //获取登陆名
        String username = request.getParameter("username");
        //获取登陆密码
        String password = request.getParameter("password");
        //获取数据库类型
        String driver = request.getParameter("driver");
        //获取数据库驱动
        if (StringUtils.isEmpty(url) || StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || StringUtils.isEmpty(driver)) {
            return null;
        }
        if (driver.equals("mysql")) {
            driver = "org.gjt.mm.mysql.Driver";
        }
        //获取数据库链接
        Class.forName(driver);
        conn = DriverManager.getConnection(url, username, password);
        databaseMetaData = conn.getMetaData();
        return databaseMetaData;
    }


    private Map<String, Object> createMapByData(ResultSet rs, String primary, String id) throws SQLException {
        Map<String, Object> map = new HashMap<String, Object>();
        //获取字段名
        String colName = rs.getString("COLUMN_NAME");
        //获取字段数据类型
        String type = rs.getString("TYPE_NAME");
        //获取注解
        String comment = rs.getString("REMARKS");
        //获取小数部分尾数
        String digits = rs.getString("DECIMAL_DIGITS");
        //获取基数
        String size = rs.getString("COLUMN_SIZE");
        //是否能为空
        String isNull = rs.getString("NULLABLE");
        map.put("fieldName", colName);
        map.put("fieldType", type);
        map.put("fieldRemark", comment);
        map.put("digits", digits);
        map.put("length", size);
        map.put("isNull", isNull);
        //如果主键值和 字段名的值一样 那么就设置为主键属性
        if (primary.equals(colName)) {
            map.put("isPrimary", 1);
        } else {
            map.put("isPrimary", 0);
        }
        String clsFieldName = changeField(colName, 2);
        map.put("clsFieldName", clsFieldName);
        map.put("tableId", id);

        //设置额外的普通参数 默认在列表上显示
        map.put("isTable", 1);
        //设置额外的普通参数 默认在表单上显示
        createIsForm(map,colName);
        //设置额外的普通参数 默认不需要排序
        map.put("isSort", 1);
        //设置额外的普通参数 默认文本框输入
        map.put("formAway", 1);
        //设置额外的普通参数 默认不需要综合查询
        map.put("isSearch", 0);
        //设置额外的普通参数 默认详情页显示
        map.put("isView", 1);





        return map;
    }

    /**
     * @param name       要转换的字段
     * @param changeType 要转换的类型 1.表名 2.字段名,3方法名
     * @return
     */


    public static String changeField(String name, int changeType) {
        String[] classNames = name.split("_");
        String className = "";
        className = MyStringChangeUtil.getString(changeType, classNames, className);
        return className;
    }


    private   void  createIsForm(Map<String, Object> map,  String colName){
        String[] autoCreate={"CREATE_TIME","UPDATE_TIME","CREATE_USER","UPDATE_USER"};
        if(Arrays.asList(autoCreate).contains(colName.toUpperCase())){
            map.put("isForm", 0);
        }else{
            map.put("isForm", 1);
        }


    }
}
